﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;

namespace ProtoGame.GameLib
{
    public class ScreenStateEffects
    {
        enum ScreenState
        {
            Starting,
            Active,
            Ending,
            Inactive
        }

        TimeSpan stopwatch = TimeSpan.Zero;
        ScreenState state = ScreenState.Inactive;

        private void CheckStopwatch()
        {
            if (state == ScreenState.Starting || state == ScreenState.Ending)
            {
                if (stopwatch <= TimeSpan.Zero)
                {
                    stopwatch = TimeSpan.Zero;
                    if (state == ScreenState.Starting)
                        state = ScreenState.Active;
                    else
                        state = ScreenState.Inactive;
                }
            }
        }

        private bool CheckState(ScreenState screenState)
        {
            CheckStopwatch();
            return screenState == state;
        }

        public TimeSpan StartingTime { get; set; }
        public TimeSpan EndingTime { get; set; }

        public byte Fade
        {
            get
            {
                const byte Opaque = byte.MaxValue;
                const byte Transparent = byte.MinValue;

                CheckStopwatch();

                switch (state)
                {
                    case ScreenState.Ending:
                        return (byte)(Opaque * (MathHelper.SmoothStep(0f, (float)StartingTime.TotalSeconds, (float)stopwatch.TotalSeconds) / StartingTime.TotalSeconds));

                    case ScreenState.Starting:
                        return (byte)(Opaque * (MathHelper.SmoothStep((float)EndingTime.TotalSeconds, 0f, (float)stopwatch.TotalSeconds) / EndingTime.TotalSeconds));

                    default:
                    case ScreenState.Active:
                        return Opaque;

                    case ScreenState.Inactive:
                        return Transparent;
                }
            }
        }

        public bool IsActive
        {
            get { return CheckState(ScreenState.Active); }
        }

        public bool IsInactive
        {
            get { return CheckState(ScreenState.Inactive); }
        }

        public bool IsStarting
        {
            get { return CheckState(ScreenState.Starting); }
        }

        public bool IsEnding
        {
            get { return CheckState(ScreenState.Ending); }
        }

        public ScreenStateEffects() { }

        public void Update(TimeSpan elapsedTime)
        {
            if (state == ScreenState.Starting || state == ScreenState.Ending)
                stopwatch -= elapsedTime;
        }

        public void WakeUp()
        {
            stopwatch = StartingTime;
            state = ScreenState.Starting;
        }

        public void GoSleep()
        {
            stopwatch = EndingTime;
            state = ScreenState.Ending;
        }
    }
}
